PICキットアッセンブラ基本プログラム

当局で実験等で使用したアッセンブラ プログラムの基本的なソースファイルです。
毎度々記述が必要かつほぼ同じな初期設定類です。
これをリネームして目的のメインソースに仕上げていきます。
ソースファイルや記載文を変更する場合がありますので、最終更新日を確認して下さい

使用する変数(RAMレジスタ領域)には使用しない部分もあると思いますので、削除や改名、アドレス変更等を行ってください。
そして無駄なコメントもありますので、同様に削除して下さい。
新たに記述するのは面倒だが削除は簡単、と言う考えです。
最終的には製作者その人なりにコンパクトにまとめて行くと、高速で動作するプログラムが出来ると思います。

基本的なアッセンブラ・プログラミング考慮事項(当局比)

1)主なサブルーチンが使用するワーク用RAM(変数)
  これはGPR(汎用RAMレジスタ)BANK0のエリア、20H~6FHを使用

2)処理データ等の一時置き場
  これはGPR・BANK1以降のエリアを使用
  いちいちBANK切り替えが必要だが、仕方がない
  余裕があればBANK0領域でも良いかなと、柔軟に考える
  因みにPIC16F1705/09は1KバイトのスタティックRAMを持っています。
  その内、下記の496バイトをユーザープログラム中に自由に使えます。(共通GPRを除く)
  ただし、RAM上にプログラムは展開できません、データ置き場としてのみです。
  その他のRAM領域は特殊機能レジスタやスタック等に使われている様です。
  BANK0:20H~6FH 80バイト
  BANK1:A0H~EFH 80バイト
  BANK2:120H~16FH 80バイト
  BANK3:1A0H~1EFH 80バイト
  BANK4:220H~26FH 80バイト
  BANK5:2A0H~2EFH 80バイト
  BANK6:320H~32FH 16バイト
  ※BSRレジスタでBANK指定する事を忘れてはいけない(忘れてもアッセンブル成功する)

3)共通GPR(RAMレジスタ)エリア
  70H~7FHの少数だが便利なので割り込みルーチン等や超広域変数置き場で使用
  ウエイトルーチンのワークをここに置いても便利かも

4)通常プログラムおよび割り込みプログラムエリア
  基本的にプログラムフラッシュROM・BANK0の領域を使う(0000H~07FFHの2Kワード)
  足りなければ、ROM・BANK1を使用するも、使用頻度の低いルーチンを置く(コールにひと工夫いる)
  因みにPIC16F1705/09は8KワードのプログラムROM領域を持っています。(0000H~1FFFH)

5)固定データの置き場
  基本的にBANK1以降に置く。
  もちろん余裕があればプログラムROM・BANK0でも可能なのは言うまでもない
  アクセスは見通しの良いFSRレジスタ関連コマンドが超便利
  プログラムROMアドレス指定は+8000Hなのを忘れてはいけない
  また、「データ」としては1アドレス(1ワード)当たり、下位8bit(1バイト)しか使えない

6)プログラムROMメモリの境界
  PICは256ワード単位の弱い境目がある様で、これを忘れると意図しないバグが発生する事がある。
  例えばPIC・F1以前のプログラムでPCLを操作した計算型ジャンプ系等です。
  因みにそれはPIC・F1で新設された命令で回避できます。
  プログラムROM・BANKの2Kワード単位の強い境界にも注意
  特にFSRを使用したからと言って、つい手抜きでFSRxLをINC/DECするとうまくないです。
  FSRを16bit単位でINC/DEC出来る命令、MOVIW/MOVWI等を使いましょう。
  境界を越えたサブルーチンコールの対処は、純正マニュアルに記してあります。


内蔵モジュール用サブルーチン
 過去に使用した物をここでまとめて行きたいと思います。
 XC8関数の様に汎用性を求めないので、モジュールアドレスや設定データ、ワークレジスタ等を認識する必要があります。
 最終的には各製作者様が使い易いように自由に変更。最適化していくのが良いのではと思います。

最終更新日 2020年02月09日
見た目はほとんど変わらないので、画像はPIC16F18326版を使い回しています









↑ NO-14 LCDモジュール

AQM1602と互換性のある、
I2C接続16桁2行LCD



基本プログラム その1

メインソースファイル

 ASM_16F1705BASIC_AQM01.asm

 ASM_16F1709BASIC_AQM01.asm

PICキットASM基本プログラム その1
16桁2行のLCDを標準ディスプレイとした場合

LCDはI2Cインターフェイスで接続するタイプを使用します。
AQM1602あるいは互換品を対象としています。

使用PICキットモジュール(基板)

NO-01 14ピンCPU基板(PIC16F1705を装着)

NO-12 I2C接続LCD表示器、あるいはNO-14LCD表示器

以上の2種のモジュールを使用します
もちろん、5V電源や配線コード類も必要です。

PICキットCPUモジュールとLCDとの接続
 LCDへはI2Cバス線が2本、電源線が2本、計4本の接続線が必要です
 ※電源線のプラスマイナスは間違わないように注意して下さい

 CPU基板側  LCD側
  RC0    SCL線
  RC1    SDA線
 ※これらはPPS機能により変更が可能です。

基本プログラム その1

左記のソースファイル及びソース内コメント文も参照して下さい
16F1705と16F1709は、RC6-RC7、RB4-RB7の6ピンが増えています。
I/O初期設定時がその分少々違いますが、コンフィグレーション設定は同じです。
パワーオンデフォルトのMSSP入力ピンは16F1705と16F1709とでは違いますので、注意が必要です。
16F1705では省略していたPPSによる入力設定を16F1709では行う必要があります。

アッセンブラでLCD等に文字を色々表示させるのは結構面倒くさいです・・・
細かな制御は可能なので無線用途等にはASM制御に軍配が上がりますが、単純に文字羅列するのはXC8のprintf()のお手軽さに敵いません。
画像はPIC16F18326版を使い回しています



↑ 14ピンCPU基板




↑ 8桁7セグLEDモジュール
Aモードで操作
このモードでは上の方の1ユニットしか制御されていない
下のユニットには事前に表示されてたデータが押し出されて表示されている






↑ Bモードでの操作
16桁での制御が可能





↑ Bモードでの操作

上記の画像は下記のデモプログラムで表示できます


基本プログラム(デモプロフラム)

 ASM_16F1709BASIC_DFR02.asm



PICキットASM基本プログラム その2
8桁7セグLEDを標準ディスプレイとした場合

これはSPIで接続するタイプで、HC595を介して7セグLEDと接続された構造となっています。
HC595出力を「L」とする事で接続セグメントが発光します。
DFR0090あるいは互換品を対象としています。
この構造を取っている7セグLEDは、簡単に増設で出来るのも特徴です
今の所、制御LED数は8個までです。
制御可能LED桁数の拡張は可能ですが、後日行いたいと思います。
MSSPは使用せず、データを受けませんので、送信しっぱなしです。
使用ポートが違うので、I2Cバスと共存できます。
また、送信のみなので、SPIポートとICSPポートと併用可能です、
と言うか、併用した方がポートの使用効率が良いのでは思います。
LCDと違い、文字も大きく自ら発光するので、とても見易いです。
また、高速で動作するので、8bitPICでは理論的にはウエイト不要です。

使用PICキットモジュール(基板)

NO-01 14ピンCPU基板(PIC16F1705を装着)

      DFR00908桁7セグLEDモジュール

以上の2種のモジュールを使用します
もちろん、5V電源や配線コード類も必要です。

PICキットCPUモジュールとLEDモジュールとの接続
 LEDへはSPIバス線が3本、電源線が2本、計5本の接続線が必要です
 ※電源線のプラスマイナスは間違わないように注意して下さい

デフォルト設定(ヘッダーファイルで変更可)
 CPU基板側  LED側

  RA0    DATA線

  RA1    LATCH線

  RA2    CLOCK線


ASM版DEF0090制御サブルーチン群 Ver2

各種変更により「DFR0090ASMv2」とさせて頂きます。
機能的にA群とB群とに分かれました。
前バージョンとのサブルーチン名が変更されました。 <m(_ _)m>
今の所、機能的にはXC8版Ver2と大きな変更ありませんが、違いもあります。
XC8版がバージョンアップしたので、何か悔しくてASM版もバージョンアップさせる事にしました・・・ (^_^;)ナンダソレ
とは言え、無線周波数表示ではVer1の方がシンプルなので、扱い易いと思います。
Ver2ではバッファや専用ワークRAMはBANK1に移動しました。
ただし、基本的な動作指令コマンド等用レジスタはBANK0のままですので、サブルーチンコールをする際はGPRのBANKを意識する必要は無いと思います。
BCD変換ルーチンも同様に変更され、一連の専用サブルーチン扱いとします。
下記の「変数」とは汎用RAMレジスタのラベル名の事です。




基本的な使用方法A(A群)
 旧来の使用方法で、32bit数値を8桁7セグLEDに表示させます。
 ただし、サブルーチン名が変更されています。
 無線周波数等の数字表示方法を使用するのを想定されています

 ①32bit符号無し整数(16進バイナリ数値)を用意
   使用変数 hex0~hex3
        上記変数に必要な数値(16進バイナリ)を用意
 ↓
 ②BCD_B1(32bit16進バイナリ数値を40bitBCDに変換)
   このサブルーチンをCALLするだけ
   入力変数 hex0-hex3
   出力変数 digit12
        digit34
        digit56
        digit78
        digit9A
 ↓
 ③SET_SBUF8(BCD出力から8桁フラグ付き数値生成)
   次にこのサブルーチンをCALLするだけ
   内部でBCD_B1出力からバッファにフラグ付数値を出力
   入力変数 digit12
        digit34
        digit56
        digit78
        digit9A
   出力変数 DBUF0-DBUF7(BANK1)
 ↓
 ④XFER_SR8L(SEGデータを生成・HC595に転送)
   さらにこのサブルーチンをCALLするだけ
   内部で③出力からセグメントデータを生成、
   HC595へ、そのデータを出力・ラッチ(表示)させます
   入力変数 DBUF0-DBUF7

 ⑤以上4ステップのメインルーチン内プログラムとなります
  下記の例では、32bitバイナリ数値「00BC614EH」を、
  10進数表記に変換し、DFR0090に送信した結果、
  「12345678」とLEDに表示されます。

 例)
   MOVLW 04EH
   MOVWF hex0
   MOVLW 061H
   MOVWF hex1
   MOVLW 0BCH
   MOVWF hex2
   MOVLW 00H
   MOVWF hex3  ;00BC614EHを設定
   ;
   CALL  BCD_B1
   CALL  SET_SBUF8
   CALL  XFER_SR8L
   ;

制御サブルーチンA群概要
 これらのサブルーチン群には「VRAM」の概念はありません。
 HC595に送信するだけの動作となります。
 扱うデータも「数値」のみです

SET_SBUF8
  40bitBCDからフラグ付き数値をバッファに生成します
  処理は最初の8桁のHC595までです。
  「BCD_B1」出力をアクセスします

  引数1:40bitBCDを「BCD_B1」出力から取得
  引数2:「FLG」8bitフラグバイト(注1)
  戻 値:専用バッファにフラグ付き数値を生成
      DBUF0~DBUF7の8バイト、8桁分
      9・10桁は切り捨て

XFER_SR8L
  フラグ付き数値を中間コードに変更後セグメントデータを生成、
  シフトレジスタに8桁分のデータ転送後ラッチ

  引数:DBUF0~DBUF7のフラグ付き数値8バイト8桁分
  戻値:無

BCD_B1
  以前の「BCD」と機能的には同じですが、Ver2専用です
  32bit16進バイナリ数値を40bitBCDに変換します
  引数:32bit16進バイナリ数値(0H~FFFFFFFFH)
     hex0~hex3

  戻値:40bitBCDを5バイトの専用変数5バイトに出力
     digit12(BANK1)
     digit34
     digit56
     digit78
     digit9A

XFER_SR1L
  Wregの1桁分数値データをHC595の最上位桁に表示させる
  既存の表示データは下位桁にシフトされる
  最下位桁は破棄される
  引数:Wレジスタの数値データ0H~FH
  戻値:無し

XFER_SR1
  Wregの1桁分数値データをシフトレジスタの最上位桁に転送させる
  既存の表示データは下位桁にシフトされる
  最下位桁は破棄される
  ラッチはしないので、表示は変わらず

  引数:Wレジスタの数値データ0H~FH
  戻値:無し


CLR_SR1
  1桁分のブランクデータをシフトレジスタに転送
  既存のシフトレジスタデータは下位桁にシフトされる

  引数:無し
  戻値:無し

CLR_SR8L
  8桁分のブランクデータをHC595に転送・表示
  既存のシフトレジスタデータは下位桁にシフトされる

  引数:無し
  戻値:無し


注1)SET_SBUF8引数2のフラグバイト
表示制御フラグ「FLG」各ビット詳細

表示桁数指令
 2桁表示指令 FLG=xxxxx001
 4桁表示指令 FLG=xxxxx011
 6桁表示指令 FLG=xxxxx101
 8桁表示指令 FLG=xxxxx111

ゼロブランキング指令
 しない    FLG=xxxx0xxx
 する     FLG=xxxx1xxx

ドット表示指令
 2,5桁点灯 FLG=x001xxxx
 3,6桁点灯 FLG=x010xxxx
 4,7桁点灯 FLG=x100xxxx



基本的な使用方法B(B群)
 このモードは標準的なLCDの使用方法を模しています。
 内部的な仮想VRAMを用意、0~FHまでのアドレスが存在します。
 VRAMの位置は「DSP_ADR」と言う名のレジスタで指定
 ホーム位置は0Hでそれが最左側LEDと言う事になります
 7セグLEDの位置とVRAMの位置は概ね一致しますが、不一致の場合有
 「DSP_ADR」で指定したアドレスに文字コードを書き込みます。
 その文字コードに対応した文字が表示されます。
 使用方法1では「数値」を扱っていますが、ここでは「文字」として扱います。
 しかし、表示される文字種は7セグLEDでは限定されてしまいます。
 A群とごっちゃに使うと表示がおかしくなる場合があります・・・


制御サブルーチンB群概要

PUTL
  DSP_ADRで指定した位置(注2)から文字列をVRAMに書き込み、
  HC595に送信・表示します
  文字列格納先頭アドレスを「MSADx」16bitで指定(注3)
  「DSP_ADR」は内部で文字列分インクリメントされます

  引数1:「DSP_ADR」
  引数2:「MSAD0」文字列先頭アドレス下位バイト
  引数3:「MSAD1」文字列先頭アドレス上位バイト
  引数4:「SEGLED」でHC595数を指定しておきます(注4)
  戻 値:無

PUTC
  指定の1桁にWregの文字コードをVRAMに書き込み、
  HC595に送信・表示されます。
  「DSP_ADR」は内部でインクリメントされます

  引数1:Wreg 文字コード
  引数2:「DSP_ADR」 仮想VRAMアドレス
  引数3:「SEGLED」でHC595数を指定しておきます

WRTD
  指定の1桁にWregの文字コードをVRAMに書き込みます
  シフトレジスタには送信されません
  「DSP_ADR」は内部でインクリメントされます

  引数1:Wreg 文字コード
  引数2:「DSP_ADR」VRAMアドレス

XFER_SRA
  仮想VRAM内容をHC595に反映させます

  引数:「SEGLED」でHC595数を指定しておきます
  戻値:無し

PTLAT
  すべてのHC595のシフトレジスタの内容をラッチさせる

  引数:無し
  戻値:無し

CLR_ALL
  VRAM等バッファ内データをクリアします。
  HC595にも反映・表示されます

  引数:「SEGLED」でHC595数を指定しておきます
  戻値:無し


注2)「DSP_ADR」について
   LCDの様に最左側のHC595がDSP_ADR=00H
   最右側の(最下流の)HC595がDSP_ADR=0FH
   となります。
   今の所、17桁以上は対応してません。


注3)「MSAD0MSAD1」について
   この変数で指定されたROM領域16bitアドレス、
   すなわち、8000H以降(0000H以降では無いので注意)を、
   文字列格納先頭アドレスと認識します。
   文字列エンドコードは00Hです。
   サブルーチン内でFSRxレジスタを使用してアクセスします。
   下記の例では、7セグLEDの先頭から「MSG」の文字列
   ”AF 1230.56”を表示します。

  使用例
   MAIN
        MOVLW 10H
        MOVWF SEGLED
        CALL  CLR_ALL
        ;
        MOVLW LOW MSG
        MOVWF MSAD0
        MOVLW HIGH MSG
        MOVWF MSAD1
        CALL  PUTL
        ;
         その他プログラム

   ;
   MSG
        DT ”AF 1230.56”
        DW 00H


注4)「SEGLED」について
   接続されているHC595制御7セグLED数を指定します。
   現在は「8」と「16」(10H)のみ指定可能です。
   Bモード動作でのみ反映されます

注5)使用できる文字コードについて
   0~9
   AbCcdEFHLnoPrUu
   - _ .~ sp等
ウエイト ソースファイル

共通事項
 専用ワークRAMレジスタ使用
 cnt0~cnt3の4バイト
 これはバンク0のRAM使用

 呼び出し方法
 CALL waitXXY
 XXは、数字によって時間を指定
 Yは、
   u マイクロセカンド
   m ミリセカンド
   s セカンド

32MHZ版

 WAIT32_01a.asm


12.8MHZ版

 WAIT12R8_01.asm


10MHZ版

 WAIT10_01.asm
ウエイト サブルーチン

必ず必要なサブルーチンで、システム周波数に合わせて用意しなければなりません。
あちこちで作成しては放置してますので、ここでまとめたいと思います
今までで、追加・変更等行っていて、どれが最新かが分からないので、このページで最終バージョンを記載する事により管理したいと思います。

基本プログラムでは32MHZ用ウエイトが有効になっています。
その他に、12.8MHZ、10MHZ、8MHZが存在します。
戻る  実験・製作の記録TOPへ戻る